const { v4: uuidv4 } = require('uuid');
const WebSocket = require('ws');

// ✅ 存储 id -> { ws, name, context, connectedAt }
const connections = new Map();

/**
 * 添加一个 WebSocket 连接
 * @param {WebSocket} ws - WebSocket 对象
 * @param {Object} context - 可选上下文数据，如昵称等
 * @returns {{id: string, name: string}}
 */
function addConnection(ws, context = {}) {
  const id = uuidv4();                    // 使用 UUID 生成唯一 ID
  const name = context.name || '匿名用户'; // 默认昵称为“匿名用户”

  // 存储连接信息：id -> { ws, name, ... }
  connections.set(id, {
    ws,
    id,
    name,
    connectedAt: new Date(),
    ...context
  });

  // 连接关闭时自动清理
  ws.on('close', () => {
    connections.delete(id);
  });

  return { id, name };
}

/**
 * 移除指定 WebSocket 连接
 * @param {WebSocket} ws - 要移除的 WebSocket 连接
 */
function removeConnection(ws) {
  for (const [id, { ws: targetWs }] of connections.entries()) {
    if (targetWs === ws) {
      connections.delete(id);
      break;
    }
  }
}

/**
 * 获取所有有效连接
 * @returns {Array<{ws: WebSocket, id: string, name: string, connectedAt: Date}>}
 */
function getAllConnections() {
  return Array.from(connections.values())
    .filter(conn => conn.ws.readyState === WebSocket.OPEN);
}

/**
 * 根据 ID 获取连接
 * @param {string} id - 用户 ID
 * @returns {WebSocket|null}
 */
function getConnectionById(id) {
  const connection = connections.get(id);
  return connection && connection.ws.readyState === WebSocket.OPEN ? connection.ws : null;
}

/**
 * 获取所有用户 ID
 * @returns {string[]}
 */
function getAllClientIds() {
  return Array.from(connections.keys());
}

/**
 * 获取用户名称
 * @param {string} id - 用户 ID
 * @returns {string}
 */
function getClientNameById(id) {
  const connection = connections.get(id);
  return connection?.name ?? '未知用户';
}

/**
 * 向所有客户端广播消息
 * @param {string} message - 要广播的消息
 */
function broadcastMessage(message) {
  getAllConnections().forEach(({ ws }) => {
    ws.send(message);
  });
}

/**
 * 向指定客户端发送消息
 * @param {string} toId - 接收者 ID
 * @param {string} message - 消息内容
 */
function sendMessageTo(toId, message) {
  const ws = getConnectionById(toId);
  if (ws) {
    ws.send(message);
  }
}

module.exports = {
  addConnection,
  removeConnection,
  getAllConnections,
  getConnectionById,
  broadcastMessage,
  sendMessageTo,
  getAllClientIds,
  getClientNameById
};
